package com.hdu.executor;

import java.math.BigDecimal;

import java.util.HashMap;

import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;

public class TestMain {

    public static void main(String[] args) {
        test3();
    }

    public static void test1() {
        // A >= 50 || C < 3

        // A >= 50
        CompileBasicExpression compileBasicExpression1 = new CompileBasicExpression();
        compileBasicExpression1.setParamName("A");
        compileBasicExpression1.setOpCode(OpCode.GTE);
        compileBasicExpression1.setThresholdValue(new BigDecimal(50));

        // B < 3
        CompileBasicExpression compileBasicExpression2 = new CompileBasicExpression();
        compileBasicExpression2.setParamName("C");
        compileBasicExpression2.setOpCode(OpCode.LT);
        compileBasicExpression2.setThresholdValue(new BigDecimal(3));

        CompileComplexExpression compileComplexExpression = CompileComplexExpression.builder()
                .logicOpCode(LogicOpCode.OR)
                .compileBasicExpressions(asList(compileBasicExpression1, compileBasicExpression2))
                .build();

        Rule rule = Rule.builder()
                .compileComplexExpression(compileComplexExpression)
                .build();

        ParamQueryService.mockParamValue(
                new HashMap<String, BigDecimal>() {{
                    put("A", new BigDecimal(50));
                    put("C", new BigDecimal(4));
                }}
        );

        RuleHitResult ruleHitResult = RuleCalService.calculate(rule);

        System.out.println(ruleHitResult);
    }

    public static void test2() {
        // (A >= 50 || C < 3) && B > 10

        // A >= 50
        CompileBasicExpression compileBasicExpression1 = new CompileBasicExpression();
        compileBasicExpression1.setParamName("A");
        compileBasicExpression1.setOpCode(OpCode.GTE);
        compileBasicExpression1.setThresholdValue(new BigDecimal(50));

        // B < 3
        CompileBasicExpression compileBasicExpression2 = new CompileBasicExpression();
        compileBasicExpression2.setParamName("C");
        compileBasicExpression2.setOpCode(OpCode.LT);
        compileBasicExpression2.setThresholdValue(new BigDecimal(3));

        // B > 10
        CompileBasicExpression compileBasicExpression3 = new CompileBasicExpression();
        compileBasicExpression3.setParamName("B");
        compileBasicExpression3.setOpCode(OpCode.GT);
        compileBasicExpression3.setThresholdValue(new BigDecimal(10));

        // (A >= 50 || C < 3)
        CompileComplexExpression compileComplexExpression = CompileComplexExpression.builder()
                .logicOpCode(LogicOpCode.OR)
                .compileBasicExpressions(asList(compileBasicExpression1, compileBasicExpression2))
                .build();

        // (A >= 50 || C < 3) && B > 10
        compileComplexExpression = CompileComplexExpression.builder()
                .logicOpCode(LogicOpCode.AND)
                .compileComplexExpressions(singletonList(compileComplexExpression))
                .compileBasicExpressions(singletonList(compileBasicExpression3))
                .build();

        Rule rule = Rule.builder()
                .compileComplexExpression(compileComplexExpression)
                .build();

        ParamQueryService.mockParamValue(
                new HashMap<String, BigDecimal>() {{
                    put("A", new BigDecimal(50));
                    put("C", new BigDecimal(2));
                    put("B", new BigDecimal(11));
                }}
        );

        RuleHitResult ruleHitResult = RuleCalService.calculate(rule);

        System.out.println(ruleHitResult);
    }

    public static void test3() {
        // ((A >= 50 || C < 3) && B > 10) && D > 20

        // A >= 50
        CompileBasicExpression compileBasicExpression1 = new CompileBasicExpression();
        compileBasicExpression1.setParamName("A");
        compileBasicExpression1.setOpCode(OpCode.GTE);
        compileBasicExpression1.setThresholdValue(new BigDecimal(50));

        // B < 3
        CompileBasicExpression compileBasicExpression2 = new CompileBasicExpression();
        compileBasicExpression2.setParamName("C");
        compileBasicExpression2.setOpCode(OpCode.LT);
        compileBasicExpression2.setThresholdValue(new BigDecimal(3));

        // B > 10
        CompileBasicExpression compileBasicExpression3 = new CompileBasicExpression();
        compileBasicExpression3.setParamName("B");
        compileBasicExpression3.setOpCode(OpCode.GT);
        compileBasicExpression3.setThresholdValue(new BigDecimal(10));

        // (A >= 50 || C < 3)
        CompileComplexExpression compileComplexExpression = CompileComplexExpression.builder()
                .logicOpCode(LogicOpCode.OR)
                .compileBasicExpressions(asList(compileBasicExpression1, compileBasicExpression2))
                .build();

        // (A >= 50 || C < 3) && B > 10
        compileComplexExpression = CompileComplexExpression.builder()
                .logicOpCode(LogicOpCode.AND)
                .compileComplexExpressions(singletonList(compileComplexExpression))
                .compileBasicExpressions(singletonList(compileBasicExpression3))
                .build();


        // D > 20
        CompileBasicExpression compileBasicExpression4 = new CompileBasicExpression();
        compileBasicExpression4.setParamName("D");
        compileBasicExpression4.setOpCode(OpCode.GT);
        compileBasicExpression4.setThresholdValue(new BigDecimal(20));

        // (A >= 50 || C < 3) && B > 10 && D > 20
        compileComplexExpression = CompileComplexExpression.builder()
                .logicOpCode(LogicOpCode.AND)
                .compileComplexExpressions(singletonList(compileComplexExpression))
                .compileBasicExpressions(singletonList(compileBasicExpression4))
                .build();

        Rule rule = Rule.builder()
                .compileComplexExpression(compileComplexExpression)
                .build();

        ParamQueryService.mockParamValue(
                new HashMap<String, BigDecimal>() {{
                    put("A", new BigDecimal(50));
                    put("C", new BigDecimal(2));
                    put("B", new BigDecimal(11));
                    put("D", new BigDecimal(5));
                }}
        );

        RuleHitResult ruleHitResult = RuleCalService.calculate(rule);

        System.out.println(ruleHitResult);
    }
}
